package com.luomu.base.biz.impl;
import java.util.*;

import com.alibaba.fastjson.JSON;
import com.luomu.base.api.bo.ChatCompletedCallBackReqBO;
import com.luomu.base.api.bo.ChatSendReqBO;
import com.luomu.base.api.bo.Message;
import com.luomu.base.api.bo.MessageChat;
import com.luomu.base.api.enmus.MessageType;
import com.luomu.base.api.enmus.UserType;
import com.luomu.base.api.service.UserChatService;
import com.luomu.base.biz.utils.OpenAISubscriber;
import com.luomu.base.biz.utils.OpenAiWebClient;
import com.luomu.base.biz.utils.UserSessionUtil;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import reactor.core.publisher.Flux;

import java.util.stream.Collectors;

/**
 * @author niuxiangqian
 * @version 1.0
 * @date 2023/3/23 14:52
 **/
@Slf4j
@RequiredArgsConstructor
@RestController
@RequestMapping("/userChatService")
public class UserChatServiceImpl implements UserChatService {

    @Autowired
    private UserSessionUtil userSessionUtil;

    @Autowired
    private  OpenAiWebClient openAiWebClient;
    /**
     * tokens和中文的转化比例
     */
    private static final float TOKEN_CONVERSION_RATE = 0.7f;
    /**
     * 最长tokens
     */
    private static final Integer MAX_TOKEN = 4096;
    /**
     * 最大中文长度
     */
    private static final Integer CHINESE_LENGTH = (int) (MAX_TOKEN / TOKEN_CONVERSION_RATE);
    private static final List<String> IMAGE_COMMAND_PREFIX = Arrays.asList("画", "找");

    @Override
    public Flux<String> sendText(ChatSendReqBO req) {

//        if (IMAGE_COMMAND_PREFIX.contains(String.valueOf(content.charAt(0)))) {
//            Message userMessage = new Message(MessageType.IMAGE, UserType.USER, content);
//            return Flux.create(emitter -> {
//                OpenAISubscriber subscriber = new OpenAISubscriber(emitter, sessionId, this, userMessage);
//                Flux<String> openAiResponse =
//                        openAiWebClient.getImage(sessionId, content);
//                openAiResponse.subscribe(subscriber);
//                emitter.onDispose(subscriber);
//            });
//        }

        String content = req.getContent();
        String sessionId = req.getSessionId();

        int currentToken = (int) (content.length() / TOKEN_CONVERSION_RATE);
        //获取历史对话 尽量保证不超过4096个tokens
        List<Message> history = userSessionUtil.getHistory(sessionId, MessageType.TEXT, (int) (CHINESE_LENGTH - currentToken));
        log.info("history:{}", history);
//        if(CollectionUtils.isEmpty(history)){
//            history = new ArrayList<>();
//            Message systemMessage= new Message();
//            systemMessage.setMessageType(MessageType.TEXT);
//            systemMessage.setUserType(UserType.system);
//            systemMessage.setMessage("你是一个具有超过10年工作经验的中秋祝福语小编，精通中国职场文化和社交礼仪。你会根据不同的发送对象（如领导、同事、合作伙伴等）自动生成合适的中秋节祝福语，帮助用户用得体的语言表达节日问候");
//            systemMessage.setDate(new Date());
//            history.add(systemMessage);
//        }

        Message message= new Message();
        message.setMessageType(MessageType.TEXT);
        message.setUserType(UserType.user);
        message.setMessage(content);
        message.setDate(new Date());
        history.add(message);

        List<MessageChat> messageChats = new ArrayList<>(history.size());
        for(Message m:history){
            if(Objects.equals(m.getMessageType(), MessageType.TEXT)){
                MessageChat messageChatItem = new MessageChat();
                messageChatItem.setRole(m.getUserType().getCode());
                messageChatItem.setContent(m.getMessage());
                messageChats.add(messageChatItem);
            }
        }


//        String prompt = JSON.toJSONString(messageChats);
//        log.info("prompt:{}", prompt);

        Message userMessage = new Message(MessageType.TEXT, UserType.user, content);

//        log.info("prompt:{}", prompt);
        return Flux.create(emitter -> {
            Flux<String> openAiResponse = openAiWebClient.getChatResponse(messageChats);
            OpenAISubscriber subscriber = new OpenAISubscriber(emitter, sessionId, this, userMessage);
            openAiResponse.subscribe(subscriber);
            emitter.onDispose(subscriber);
        });
    }

    @Override
    public List<Message> getHistory(ChatSendReqBO chatSendReqBO) {
        return userSessionUtil.getHistory(chatSendReqBO.getSessionId(), null, Integer.MAX_VALUE);
    }

    @Override
    public void completed(ChatCompletedCallBackReqBO req) {
         Message questions =req.getQuestions();
         String response = req.getResponse();
         String sessionId = req.getSessionId();
        userSessionUtil.addMessage(sessionId, questions);
        userSessionUtil.addMessage(sessionId, new Message(questions.getMessageType(), UserType.assistant, response));
        System.out.println(response);
    }

    @Override
    public void fail(ChatCompletedCallBackReqBO req) {
        Message questions =req.getQuestions();
        String sessionId = req.getSessionId();
        String errorMsg = req.getErrorMsg();
        log.error("openai 处理失败 sessionId:{},questions:{},errorMsg:{}", sessionId, questions, errorMsg);
    }

    @Override
    public void clearHistory(ChatCompletedCallBackReqBO req) {
        String sessionId = req.getSessionId();
        log.info("清除历史记录 sessionId:{}", sessionId);
        userSessionUtil.clearHistory(sessionId);
    }
}
